<template>
  <div>
    <!-- 导航栏 -->
    <van-nav-bar title="编辑资料" left-arrow @click-left="$router.back()" />

    <!-- 头像区域 -->
    <div class="avatar-box">
      <van-image :src="userInfo.photo" fit="cover" round></van-image>
      <van-uploader :after-read="afterRead" />
    </div>

    <!-- 三个cell -->
    <van-cell-group>
      <van-cell
        @click="clickNameCell"
        title="名称"
        :value="userInfo.name"
        is-link
      />
      <van-cell @click="genderShow = true" title="性别" :value="userInfo.gender == '1' ? '女' : '男'" is-link />
      <van-cell
        @click="clickBirthCell"
        title="生日"
        :value="userInfo.birthday"
        is-link
      />
    </van-cell-group>

    <!-- 修改名字的地方 -->
    <!-- v-model用来控制显示或隐藏的 -->
    <van-dialog
      :before-close="beforeClose"
      @confirm="saveName"
      v-model="nameShow"
      title="修改昵称"
      show-cancel-button
    >
      <van-field ref="nameField" v-model="editName" class="name-field" />
    </van-dialog>

    <!-- 修改生日的地方 -->
    <!-- v-model用来控制显示或隐藏的 -->
    <van-popup v-model="birthShow" position="bottom">
      <!-- v-model用来双向绑定选择的日期 -->
      <!-- min-date:设置允许选择的最小日期 -->
      <!-- max-date:设置允许选择的最大日期 -->
      <van-datetime-picker
        @confirm="saveBirthday"
        @cancel="birthShow = false"
        v-model="currentDate"
        type="date"
        title="选择年月日"
        :min-date="minDate"
        :max-date="maxDate"
      />
    </van-popup>

    <!-- 裁剪区域的盒子 -->
    <div v-show="cropShow" class="crop-box">
      <vueCropper
        ref="cropper"
        autoCrop
        autoCropWidth="200"
        autoCropHeight="200"
        :img="cropImg"
      ></vueCropper>

      <van-button @click="doCrop" type="primary">裁剪</van-button>
      <van-button @click="cropShow = false" style="right: 0" type="primary"
        >取消</van-button
      >
    </div>

    <!-- 弹出层：修改性别 -->
    <van-popup class="gender-pop" v-model="genderShow" position="bottom">
      <van-nav-bar title="修改性别" left-text="取消" />

      <van-cell @click="editGender('0')" title="男" is-link />
      <van-cell @click="editGender('1')" title="女" is-link />
    </van-popup>
  </div>
</template>
<script>
import { editUserInfoAPI, editPhotoAPI } from "@/api/user";
// 导入dayjs
import dayjs from "dayjs";
// 导入插件
import { VueCropper } from "vue-cropper";
export default {
  components: {
    VueCropper,
  },
  data() {
    return {
      genderShow: false,
      // 控制裁剪区域的显示和隐藏
      cropShow: false,
      // 裁剪图片地址
      cropImg: "",
      nameShow: false,
      // 控制生日弹出层的显示和隐藏
      birthShow: false,
      editName: "",
      // 双向绑定日期（可以设置当前时间）
      currentDate: new Date("2000-1-1"),
      // 能选择的最小日期
      minDate: new Date("1949-10-1"),
      // 能选择的最大日期
      maxDate: new Date(),
    };
  },
  methods: {
    async editGender (gender) {
      
      // 发请求给服务器去修改
      await editUserInfoAPI({
        gender
      })

      // 保存到vuex里
      this.$store.commit('changeUserInfo', {
        ...this.userInfo,
        gender
      })
      // 隐藏弹出层
      this.genderShow = false
    },
    // 点击裁剪触发
    doCrop() {
      
      // 调用裁剪插件的获取截图图片的方法（得到的是file对象）
      this.$refs.cropper.getCropBlob(async (data) => {

          // 这个时候就可以调用接口上传图片
          // ajax要上传图片必须依赖FormData
          const fm = new FormData()
          fm.append('photo', data)
          const res = await editPhotoAPI(fm)
          
          // 把上传成功后的图片地址存到vuex里
          this.$store.commit('changeUserInfo', {
            ...this.userInfo,
            photo: res.data.photo // 把服务器返回的最新地址给到photo
          })
          // 隐藏裁剪框
          this.cropShow = false
      });
    },
    // 选择完图片触发
    afterRead(file) {
      // file里有两个属性重要：
      //    file.file 这个属性你刚刚所选择的文件对应的文件对象
      //    file.content 可以得到这个文件对应的base64形式（可以当做路径直接显示）
      //    console.log('触发了', file.content)

      // 显示出裁剪框
      this.cropShow = true;
      // 把选择的图片交给裁剪框去裁剪
      this.cropImg = file.content;
    },
    // 点击名字cell
    async clickNameCell() {
      // 1. 显示出对话框
      this.nameShow = true; // dom还没渲染，因为dom渲染使异步的，要等当前的同步代码执行完毕才会执行异步代码
      // 2. 让输入框显示当前的昵称
      this.editName = this.userInfo.name;
      // 3. 让输入框获得焦点
      // 要等下次dom更新完毕调用
      await this.$nextTick();
      // console.log(this.$refs.nameField);
      // 这里的代码是dom更新后调用的
      this.$refs.nameField.focus();
    },
    // 点击确认保存名字
    async saveName() {
      // 先做非空判断
      if (this.editName == "") return this.$toast("请输入要修改的名字");
      // 调用接口修改
      await editUserInfoAPI({
        name: this.editName,
      });

      // 要让界面跟着改变(改vuex里的userInfo)
      this.$store.commit("changeUserInfo", {
        ...this.userInfo,
        name: this.editName,
      });
      // 弹出提示
      this.$toast("修改成功！");
      // 让弹出框隐藏
      this.nameShow = false;
    },

    // 阻止默认关闭
    beforeClose(action, done) {
      // 阻止关闭
      done(false);
    },

    // 点击生日cell
    clickBirthCell() {
      // 显示出生日弹出层
      this.birthShow = true;
      // 把当前的生日赋值跟时间选择器双向绑定的数据（也就是设置它默认显示值）
      this.currentDate = new Date(this.userInfo.birthday);
    },

    // 保存生日的事件
    async saveBirthday() {
      // 把时间选择器里拿到的日期对象转成字符串
      const birthday = dayjs(this.currentDate).format("YYYY-MM-DD");
      // 发请求
      await editUserInfoAPI({
        birthday,
      });

      // 修改成功存到vuex里
      this.$store.commit("changeUserInfo", {
        ...this.userInfo,
        birthday,
      });
      this.$toast("修改成功");
      // 隐藏弹出层
      this.birthShow = false;
    },
  },
  computed: {
    // 用计算属性简化对vuex里数据的访问
    userInfo() {
      return this.$store.state.userInfo;
    },
  },

  async created() {
    // 调用vuex里actions方法发请求获取用户信息
    // 存到vuex里
    this.$store.dispatch("reqUserInfo");
  },
};
</script>

<style lang="less" scoped>
.avatar-box {
  height: 140px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;

  .van-image {
    width: 120px;
    height: 120px;
  }

  .van-uploader {
    position: absolute;
    left: 0;
    top: 0;

    ::v-deep .van-uploader__upload {
      position: absolute;
      left: 0;
      top: 0;
      width: 100vw;
      height: 140px;
      // 能让这个东西看不见，但是它还在
      // 为什么要这么做？因为我既想要他的功能，又不想看到他
      opacity: 0;
    }
  }
}

.name-field {
  border: 1px solid #ddd;
}

.van-popup {
  height: 200px;
}

.crop-box {
  width: 100vw;
  height: 100vh;
  position: fixed;
  left: 0;
  top: 0;

  .van-button {
    position: absolute;
    bottom: 0;
  }
}

.gender-pop {
  height: 140px;
}
</style>